package myset

import "sync"

type shit struct{}

type Set[T comparable] struct {
	inner map[T]shit
}

func NewSet[T comparable]() *Set[T] {
	return &Set[T]{
		inner: make(map[T]shit, 0),
	}
}

func (st *Set[T]) Set(v T) {
	st.inner[v] = shit{}
}

func (st *Set[T]) Exist(v T) bool {
	if _, exists := st.inner[v]; exists {
		return true
	}
	return false
}

func (st *Set[T]) Remove(v T) {
	delete(st.inner, v)
}

type ConcurrentSet[T comparable] struct {
	inner Set[T]
	mu    sync.RWMutex
}

func (st *ConcurrentSet[T]) Set(v T) {
	st.mu.Lock()
	defer st.mu.Unlock()
	st.Set(v)
}

func (st *ConcurrentSet[T]) Exist(v T) bool {
	st.mu.RLock()
	defer st.mu.RUnlock()
	return st.Exist(v)
}

func (st *ConcurrentSet[T]) Remove(v T) {
	st.mu.Lock()
	defer st.mu.Unlock()
	st.Remove(v)
}
